//
// Created by denglibin on 19-4-13.
//
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
/*
1. 函数说明
进程通信-pipe 匿名管道
pipe（建立管道）：
1) 头文件 #include<unistd.h>
2) 定义函数： int pipe(int filedes[2]);
3) 函数说明： pipe()会建立管道，并将文件描述词由参数filedes数组返回。
              filedes[0]为管道里的读取端
              filedes[1]则为管道的写入端。
4) 返回值：  若成功则返回零，否则返回-1，错误原因存于errno中。

1.管道只允许具有血缘关系的进程间通信，如父子进程间的通信。

2.管道只允许单向通信。

3.管道内部保证同步机制，从而保证访问数据的一致性。

4.面向字节流

5.管道随进程，进程在管道在，进程消失管道对应的端口也关闭，两个进程都消失管道也消失
*/
static int main_(void)
{
    int fd[2];
    int len;
    pid_t pid;
    int ret = pipe(fd);
    if(ret == -1)
    {
        perror("pipe error");
        exit(1);
    }
    pid = fork();
    if(pid == -1)
    {
        perror("fork error");
        exit(1);
    }
    else if(pid == 0) //子进程 读取数据 需关闭写端
    {
        //关闭写端
        close(fd[1]);
        char buf[1024];
        do{
            memset(buf,0,sizeof(buf));
            len = read(fd[0],buf,sizeof(buf));//read()会把参数fd所指的文件传送nbyte个字节到buf指针所指的内存中。若参数nbyte为0，则read()不会有作用并返回0。返回值为实际读取到的字节数，
            //如果返回0，表示已到达文件尾或无可读取的数据。错误返回-1,并将根据不同的错误原因适当的设置错误码。

            write(STDOUT_FILENO,buf,len); //输出到标准输出设备
        }while(len>0);

    }
    else
    {
        //父进程 写 需关闭读端
        close(fd[0]);
        sleep(3);
        char * string = "hello pipe\n";
        write(fd[1],string, strlen(string));

    }

    return 0;
}

